组件父子
组件数据父传子
React数据流动是单向的
父组件通过向子组件传递 props,子组件得到 props 后进行相应的处理。
父组件 Parent.js
1 | import React, { Component } from "react"; |
子组件 Child.js
1 | import React, { Component } from "react"; |
页面显示效果
组件数据子传父
利用回调函数,可以实现子组件向父组件通信:父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通信。
子组件 Child.js
1 | import React, { Component } from "react"; |
父组件 Parent.js
1 | import React, { Component } from "react"; |
页面显示效果
跨级组件通信
所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:
- 中间组件层层传递
props
- 使用
context
对象
对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props
,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。不过这种方式也是可行的,当组件层次在三层以内可以采用这种方式,当组件嵌套过深时,采用这种方式就需要斟酌了。
使用 context
是另一种可行的方式,context
相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。
使用 context
也很简单,需要满足两个条件:
- 上级组件要声明自己支持
context
,并提供一个函数来返回相应的context
对象 - 子组件要声明自己需要使用
context
组件数据父传孙
父组件 parent.js
1 | import React, { Component } from "react"; |
子组件 Child.js
1 | import React, { Component } from "react"; |
孙组件 subChild.js
1 | import React, { Component } from "react"; |
页面显示效果
组件数据孙传父
父组件 Parent.js
1 | import React, { Component } from "react"; |
子组件 Child.js
1 | import React, { Component } from "react"; |
孙组件 SubChild.js
1 | import React, { Component } from "react"; |
页面显示效果
如果是父组件向子组件单向通信,可以使用变量,如果子组件想向父组件通信,同样可以由父组件提供一个回调函数,供子组件调用,回传参数。
在使用 context
时,有两点需要注意:
- 父组件需要声明自己支持
context
,并提供context
中属性的PropTypes
- 子组件需要声明自己需要使用
context
,并提供其需要使用的context
属性的PropTypes
- 父组件需提供一个
getChildContext
函数,以返回一个初始的context
对象
如果组件中使用构造函数(constructor)
,还需要在构造函数中传入第二个参数 context
,并在 super
调用父类构造函数是传入 context
,否则会造成组件中无法使用 context
。
改变 context 对象
不应该也不能直接改变 context
对象中的属性,要想改变 context
对象,只有让其和父组件的 state
或者 props
进行关联,在父组件的 state
或 props
变化时,会自动调用 getChildContext
方法,返回新的 context
对象,而后子组件进行相应的渲染。
createContext
在 16.4.1 之后,context api 遭到废弃,启用新的 createContext api
Context 的使用基于生产者消费者模式
Context.js
1 | import React from "react"; |
Parent.js
1 | import React, {Component} from "react"; |
Child.js
1 | import React, {Component} from "react"; |
SubChild.js
1 | import React, { Component } from "react"; |